#include "UIDFactory.h"
#include "Log.h"
#include "TimeUtil.h"

CUIDFactory::CUIDFactory()
{
}


CUIDFactory::~CUIDFactory()
{
}

bool CUIDFactory::Init(int iServerID /*= 0 */)
{
    m_iServerID = iServerID;
    LOG_INFO("Factory init Server is %d", m_iServerID);

    return true;
}

uint64_t CUIDFactory::CreateUID(EnmUIDType enmType)
{
    /*!< 为了创建唯一标识,存储一些临时变量. 0:类型,1:时间戳,2:递增值 */
    /*!< 在同一时间戳下,每个唯一标识都是增加递增值 */
    /*!< 当时间变动时,当前时间比记录时间大,递增值归零 */
    /*!< 当时间变动时,当前时间比记录时间小或等,时间用记录时间,递增值继续增加 */
    /*!< 同一时间戳下,递增值递增至最大值时,递增时间戳,递增值清零 */
    static int ayUIDInfo[EnmUIDType::ENM_UID_TYPE_MAX][3] = {
        {ENM_UID_TYPE_ERROR,0,0},
        {ENM_UID_TYPE_ACC,0,0},
        {ENM_UID_TYPE_ROLE,0,0},
    };


    if (ayUIDInfo[enmType][0] != enmType)
    {
        LOG_ERR("UidInfo Init Fail,Type not is index.type:%d, index type:%d", enmType, ayUIDInfo[enmType][0]);
        return 0;
    }

    int64_t ullCurTime = CTimeUtil::GetCurSecond();
    if (ullCurTime > ayUIDInfo[enmType][1])
    {
        ayUIDInfo[ullCurTime][1] = ullCurTime;
        ayUIDInfo[ullCurTime][2] = 0;
    }

    if (ayUIDInfo[enmType][2] >= INDEX_MAX)
    {
        ++ayUIDInfo[enmType][1];
        ayUIDInfo[enmType][2] = 0;
        LOG_WARN("create uid too fast, use future timestamp. time:%lld", );
    }

    uint64_t ullUID = 0;
    ullUID += (((uint64_t)m_iServerID) << OFFSET_SERVER);
    ullUID += (((uint64_t)ayUIDInfo[enmType][0]) << OFFSET_TYPE);
    ullUID += (((uint64_t)ayUIDInfo[enmType][1]) << OFFSET_TIMESTAMP);
    ullUID += (((uint64_t)ayUIDInfo[enmType][2]) << OFFSET_INDEX);

    ++ayUIDInfo[enmType][2];

    return ullUID;
}
